#pragma once
#ifndef LIGHTING_SHADOWSERVER_H
#define LIGHTING_SHADOWSERVER_H
//------------------------------------------------------------------------------
/**
    @class Lighting::ShadowServer
    
    The ShadowServer setups and controls the global aspects of the dynamic
    shadow system.
    
    (C) 2007 Radon Labs GmbH
*/
#include "core/refcounted.h"
#include "core/singleton.h"
#include "lighting/abstractlightentity.h"
#include "frame/frameshader.h"
#include "coregraphics/rendertarget.h"

//------------------------------------------------------------------------------
namespace Lighting
{
class ShadowServer : public Core::RefCounted
{
    DeclareClass(ShadowServer);
    DeclareSingleton(ShadowServer);
public:
    /// constructor
    ShadowServer();
    /// destructor
    virtual ~ShadowServer();

    /// open the shadow server
    void Open();
    /// close the shadow server
    void Close();
    /// return true if shadow server is open
    bool IsOpen() const;

    /// begin shadow frame
    void BeginFrame();
    /// begin attaching visible shadow casting light sources
    void BeginAttachVisibleLights();
    /// attach a visible shadow casting light source
    void AttachVisibleLight(const Ptr<AbstractLightEntity>& lightEntity);
    /// end attaching visible shadow casting light sources
    void EndAttachVisibleLights();
    /// update shadow buffer
    void UpdateShadowBuffer();
    /// end lighting frame
    void EndFrame();

    /// get pointer to shared shadow buffer resource
    const Ptr<CoreGraphics::Texture>& GetShadowBufferTexture() const;

private:
    static const int MaxNumShadowLights = 4;

    bool isOpen;
    bool inBeginFrame;
    bool inBeginAttach;
    Util::Array<Ptr<AbstractLightEntity>> visibleLightEntities;
    Ptr<Frame::FrameShader> frameShader;
    Ptr<Frame::FramePostEffect> finalPostEffect;
    Ptr<CoreGraphics::RenderTarget> shadowBuffer;
};

//------------------------------------------------------------------------------
/**
*/
inline bool
ShadowServer::IsOpen() const
{
    return this->isOpen;
}

//------------------------------------------------------------------------------
/**
*/
inline const Ptr<CoreGraphics::Texture>&
ShadowServer::GetShadowBufferTexture() const
{
    return this->shadowBuffer->GetResolveTexture();
}

} // namespace Lighting
//------------------------------------------------------------------------------
#endif
